package com.pocket.insight.base.sql;

import com.pocket.insight.base.mql.TypedVal;
import com.pocket.insight.entity.Dataset;
import com.pocket.insight.entity.ME;
import com.pocket.insight.entity.Type;

import java.util.List;

/**
 * 描述：数据库方言支持
 * 方法分类：
 *  1. 数据库版本信息【conn-version-info】 start at {@link Dialect#getMajorVersion}
 *
 * @author shuize
 * @create 2024/11/29
 */
public interface Dialect<T> {

    /********************************* 1. 标识符差异配置 *********************************/
    // 转义字符
    String escString(String s);

    // 左引用符
    String getLeftQuoteChar();

    // 右引用符
    String getRightQuoteChar();

    // 为 字符串 添加引用符
    String quoteString(String s);

    // 为 路径 添加引用符
    String quotePath(List<String> paths);

    // 为 路径 添加引用符
    String quotePathName(String pathName);

    // 为 表名 添加引用符
    String quoteTableName(String tableName);

    // 为 不拆分表名 添加引用符
    String quoteTableNameWithoutSplit(String tableName);

    // 为 字段 添加引用符
    String quoteFieldName(String fieldName);

    // 为 带表名和别名的字段名 添加引用符
    String quoteFieldName(String tableName, String fieldName, String baseTableAlias);

    // 为 实体[todo ] 添加引用符
    String quoteEntity(String paramString);

    // 为 单实体[todo ] 添加引用符
    String unquoteSingleEntity(String s);

    // 为 字段别名 添加引用符
    String quoteAliasName(String aliasName);

    // 为 排序字段别名 添加引用符
    String quoteOrderByAliasName(TypedVal val);

    // 为 聚合字段别名 添加引用符
    String quoteGroupByFieldName(TypedVal val);

    default void quoteStringConstant(ME expr, TypedVal val) {
    }

    default String ddlQuoteFieldName(String fieldName) {
        return quoteFieldName(fieldName);
    }

















    /********************************* 数据库差异配置 *********************************/


    TypedVal setPage(TypedVal query, Long offset, Long limit);

    default boolean supportWithInSubquery() {
        return false;
    }

    default boolean supportWith() {
        return true;
    }


    /********************************* 数据库版本信息【conn-version-info】 *********************************/
    Dialect setVersion(long majorVersion, long minorVersion);

    long getMajorVersion();

    long getMinorVersion();

    Dialect setDbProVersion(String dbProVersion);

    String getDbProVersion();

    Dialect setDbProName(String dbProName);

    String getDbProName();

    /********************************* SQL 语句构建 *********************************/
    String fieldAsAlias(String field, String alias);






    // 获取空表
    String getEmptyTable();

    default boolean canGroupByIndex() {
        return false;
    }


    default boolean aliasInOrderBy() {
        return true;
    }

    boolean isAliasAmbiguousInJoin();

    // 判断在使用offset和limit时是否需要order by。在某些数据库中，使用offset和limit时，如果不指定order by，可能会导致返回的结果集顺序不一致
    boolean isOffsetLimitRequiresOrderBy();


    String nullsOrder(String sortStr, String direction, String nullsOrder);

    String nullsOrder(String sortStr, String direction, TypedVal.EvalScope scope, String nullsOrder);

    TypedVal reformCustomQuery(String customQuery);

    TypedVal createTableVal(List<String> tablePath);

    /*********************************  *********************************/

    boolean isJsonAvailable();

    boolean isBoolAvailable();

    Object jodaToNativeParseFormat(String param);

    T boolToSqlLiteral(Boolean value);

    default boolean supportPushToMemory() {
        return true;
    }

    default String nullVal() {
        return "null";
    }

    default String getDialectName() {
        return this.getClass().getSimpleName().replace(Dialect.class.getSimpleName(), "");
    }

    Dialect setDoQuote(boolean paramBoolean);


    default boolean isNoSqlDialect() {
        return false;
    }

    default Type.TypeName getRealTypeByNativeType(Dataset.Field field) {
        return null;
    }

}
